/***
 * 文件服务：文件的上传与下载
 */

import Vue from 'vue'
import axios from 'axios'
import CryptoJS from 'crypto-js'
import store from './vuex/store'

/**
 * 转换字节顺序为32一组
 * @param val
 * @returns {number}
 */
function swapX32(val) {
  return (((val & 0xFF) << 24) | ((val & 0xFF00) << 8) | ((val >> 8) & 0xFF00) | ((val >> 24) & 0xFF)) >>> 0
}

/**
 * 将ArrayBuffer 转换为 CryptoJS 的 WordArray
 * @param arrayBuffer Buffer
 * @returns wordArray
 */
function arrayBufferToWordArray(arrayBuffer) {
  var fullWords = Math.floor(arrayBuffer.byteLength / 4)
  var bytesLeft = arrayBuffer.byteLength % 4

  var u32 = new Uint32Array(arrayBuffer, 0, fullWords)
  var u8 = new Uint8Array(arrayBuffer)

  var cp = []
  for (var i = 0; i < fullWords; ++i) {
    cp.push(swapX32(u32[i]))
  }

  if (bytesLeft) {
    var pad = 0
    for (let i = bytesLeft; i > 0; --i) {
      pad = pad << 8
      pad += u8[u8.byteLength - i]
    }

    for (let j = 0; j < 4 - bytesLeft; ++j) {
      pad = pad << 8
    }

    cp.push(pad)
  }

  return CryptoJS.lib.WordArray.create(cp, arrayBuffer.byteLength)
}

/**
 * 获取文件的hash值
 * @param file 文件数据
 * @return {Promise}
 */
function readFileHash(file) {
  return new Promise((resolve, reject) => {
    var reader = new window.FileReader()
    reader.onload = (e) => {
      let hash = CryptoJS.MD5(arrayBufferToWordArray(e.target.result)).toString()
      resolve(hash)
    }
    reader.onerror = (e) => {
      console.error('在获取文件hash时，读取文件失败')
      reject(e)
    }
    reader.readAsArrayBuffer(file)
  })
}

/**
 * 上传文件
 * @param fileName 文件名
 * @param file 文件对象
 * @param targetId 文件归属组织(选填)
 * @returns {*}
 */
async function upload(fileName, file, url , targetId) {
  let hash = await readFileHash(file)
  let fileInfo = {'fileName': fileName, 'fileHash': hash}
  // 旧的文件服务端口为8003，这里是用新的文件服务接口，端口为8004
  console.log('00000000000000000上传地址：' + url)
  // 封装异步对象
  return new Promise((resolve, reject) => {
    let formData = new window.FormData()
    if (targetId) {
      fileInfo.targetId = targetId
    }
    formData.append('file', file)
    formData.append('ct', JSON.stringify(fileInfo))
    console.log('window.FormData()', formData)
    axios({
      method: 'post',
      url: url,
      responseType: 'json',
      data: formData
    }).then(response => {
      if (/ERR_/.test(response.data)) {
        let errorJson = JSON.parse(response.data.substr(4))
        reject(errorJson)
      } else {
        resolve(response.data)
      }
      // console.log(response.data, response.data.fileId)
      // return response.data.fileId
    }).catch(e => {
      console.error('上传文件请求失败', e)
      reject(e)
    })
  })
}

/***
 * 下载文件
 */
async function download(url) {
  let promise = new Promise((resolve, reject) => {
    axios({
      method: 'get',
      url: url ,
      responseType: 'blob'
    }).then(response => {
      if (/ERR_/.test(response.data)) {
        let errorJson = JSON.parse(response.data.substr(4))
        reject(errorJson)
      } else {
        let reader = new window.FileReader()
        reader.onloadend = function (e) {
          resolve(e.target.result)
        }
        reader.readAsDataURL(response.data)
      }
    }).catch(e => {
      console.error('下载文件请求失败', e)
      reject(e)
    })
  })
  return promise
}
export {upload, download}
